package com.fw.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.fw.core.Controller;
import com.fw.utils.StringUtils;

public abstract class Routes {

	private final Map<String, Class<? extends Controller>> map = new HashMap<String, Class<? extends Controller>>();
	private final Map<String, String> viewPathMap = new HashMap<String, String>();

	public abstract void config();

	public Routes add(Routes routes) {
		if (routes != null) {
			routes.config();
			map.putAll(routes.map);
			viewPathMap.putAll(routes.viewPathMap);
		}
		return this;
	}

	public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath) {
		if (StringUtils.isBlank(StringUtils.trimToNull(controllerKey))) {
			throw new IllegalArgumentException("The controllerKey can not be blank");
		}
		controllerKey = controllerKey.trim();
		if (controllerClass == null) {
			throw new IllegalArgumentException("The controllerClass can not be null");
		}
		if (map.containsKey(controllerKey)) {
			throw new IllegalArgumentException("The controllerKey already exists");
		}

		if (!controllerKey.startsWith("/")) {
			controllerKey = "/" + controllerKey;
		}
		map.put(controllerKey, controllerClass);

		if (StringUtils.isBlank(StringUtils.trimToNull(viewPath))) { // view path is controllerKey by default
			viewPath = controllerKey;
		}
		viewPath = StringUtils.trimToEmpty(viewPath);
		if (!viewPath.startsWith("/")) { // "/" added to prefix
			viewPath = "/" + viewPath;
		}
		if (!viewPath.endsWith("/")) { // "/" added to postfix
			viewPath = viewPath + "/";
		}
		if (baseViewPath != null) { // support baseViewPath
			viewPath = baseViewPath + viewPath;
		}
		viewPathMap.put(controllerKey, viewPath);
		return this;
	}

	public Routes add(String controllerkey, Class<? extends Controller> controllerClass) {
		return add(controllerkey, controllerClass, controllerkey);
	}

	public Set<Entry<String, Class<? extends Controller>>> getEntrySet() {
		return map.entrySet();
	}

	public String getViewPath(String key) {
		return viewPathMap.get(key);
	}

	private static String baseViewPath;

	static void setBaseViewPath(String baseViewPath) {
		if (StringUtils.isBlank(StringUtils.trimToNull(baseViewPath))) {
			throw new IllegalArgumentException("The baseViewPath can not be blank");
		}
		baseViewPath = StringUtils.trimToEmpty(baseViewPath);
		if (!baseViewPath.startsWith("/")) { // add prefix "/"
			baseViewPath = "/" + baseViewPath;
		}
		if (baseViewPath.endsWith("/")) { // remove "/" in the end of baseViewPath
			baseViewPath = baseViewPath.substring(0, baseViewPath.length() - 1);
		}
		Routes.baseViewPath = baseViewPath;
	}
}
